library(ggplot2)
library(dplyr)
library(grid)
# --- Step positions ---
steps <- tibble(
step = c("1", "2", "3", "4"),
x = c(0, 1.7, 0, -1.7),
y = c(1.2, 0, -1.4, 0),
label = c(
"1. State\nHypothesis",
"2. Calculate\nObserved",
"3. Shuffle &\nRecalculate",
"4. Collect in\nDistribution"
),
fill = c("#10b981", "#f59e0b", "#ef4444", "#8b5cf6")
)
center <- data.frame(x = 0, y = 0)
ggplot() +
# ---- CURVED DASHED ARROWS (draw FIRST) ----
# 1 -> Center
geom_curve(
aes(x = 0, y = 1.0, xend = 0.15, yend = 0.45),
curvature = 0.35,
arrow = arrow(type = "closed", length = unit(0.4, "cm")),
linetype = "dashed",
linewidth = 1.6,
color = "#1e40af"
) +
# 2 -> 3
geom_curve(
aes(x = 1.3, y = -0.1, xend = 0.2, yend = -1.0),
curvature = 0.4,
arrow = arrow(type = "closed", length = unit(0.4, "cm")),
linetype = "dashed",
linewidth = 1.6,
color = "#1e40af"
) +
# 3 -> 4
geom_curve(
aes(x = 0, y = -1.05, xend = -1.2, yend = -0.1),
curvature = 0.45,
arrow = arrow(type = "closed", length = unit(0.4, "cm")),
linetype = "dashed",
linewidth = 1.6,
color = "#1e40af"
) +
# 4 -> Center
geom_curve(
aes(x = -1.2, y = 0.1, xend = -0.2, yend = 0.4),
curvature = -0.4,
arrow = arrow(type = "closed", length = unit(0.4, "cm")),
linetype = "dashed",
linewidth = 1.6,
color = "#1e40af"
) +
# ---- CENTER REPEAT CIRCLE ----
geom_point(
data = center,
aes(x = x, y = y),
size = 95, shape = 21,
fill = "#2563eb",
color = "#1e40af",
stroke = 4
) +
annotate(
"text", x = 0, y = 0.1,
label = "REPEAT",
color = "white",
fontface = "bold",
size = 8
) +
annotate(
"text", x = 0, y = -0.15,
label = "10,000\nTIMES",
color = "white",
fontface = "bold",
size = 7
) +
# ---- OUTER STEP CIRCLES ----
geom_point(
data = steps,
aes(x = x, y = y),
size = 48, shape = 21,
fill = steps$fill,
color = "white",
stroke = 3
) +
geom_text(
data = steps,
aes(x = x, y = y, label = label),
color = "white",
fontface = "bold",
size = 5.4,
hjust = 0.5,
vjust = 0.5
) +
# ---- STEP 5 (PILL SHAPE) ----
geom_label(
aes(x = 0, y = 1.85, label = "5. Compare & Conclude"),
fill = "#06b6d4",
color = "white",
fontface = "bold",
size = 5,
label.size = 0,
label.padding = unit(0.45, "lines")
) +
# ---- THEME ----
coord_fixed() +
xlim(-2.6, 2.6) +
ylim(-2.2, 2.3) +
theme_void() +
labs(
title = "Design 1: Circular Process Flow",
subtitle = "Permutation test logic with repeated resampling",
caption = "Steps 2–4 repeat many times to create a null distribution without parametric assumptions."
) +
theme(
plot.title = element_text(size = 22, face = "bold", hjust = 0.5),
plot.subtitle = element_text(size = 14, hjust = 0.5),
plot.caption = element_text(size = 11, hjust = 0.5)
)